<?php
namespace app\admin\model;

use app\common\model\Base;

class Menu extends Base
{

    protected $pk = 'id';
    protected $name = 'menu';
    protected $menu_id;
    protected $child_node = [];
    protected $request;

    protected function initialize()
    {
        $this->request = request();
    }

    /**
     * 菜单
     * @param $parentid 父ID
     * @param int $with_self 是否包含自己
     */
    final public function adminMenu($parentid, $with_self = 0)
    {
        // 缓存
        $menu_cache = cache('menu');
        //如果缓存不存在，则生成缓存
        if (empty($menu_cache)) {
            $menu_cache = $this->getCache();
        }
        //下级菜单，本菜单初始化
        $array = $array2 = [];
        foreach ($menu_cache as $k => $item) {
            if ($item['parentid'] == $parentid) {
                $array[$k] = $item;
            }
        }
        //如果包含本菜单，则合并数组
        if ($with_self == 1 && $parentid != 0) {
            $array2[] = isset($menu_cache[$parentid]) ? $menu_cache[$parentid] : [];
            $array = array_merge($array2, $array);
        }
        return $array;
    }


    //子菜单
    public function subMenu($parentid = 0)
    {
        $module = strtolower($this->request->module());
        $controller = strtolower($this->request->controller());
        $action = strtolower($this->request->action());
        $parentid = intval($parentid);
        //如果没有获取到菜单ID，则重新获取
        if ($parentid < 1) {
            $parentid = (int)$this->where(['app' => $module, 'controller' => $controller, 'action' => $action])->value('id');
            $this->menu_id = $parentid;
        }
        $array = self::adminMenu($parentid, 1);
        if (empty($array) || empty($array[0])) {
            return '';
        }
        $str = '';
        foreach ($array as $item) {
            if ($item['parentid'] == 0 || empty($item['app'])) {
                continue;
            }
            //是否有附加参数，只允许添加一个附加参数
            //$param = empty ($item ['data']) ? [] : explode(' = ', $item['data']);
            $classname = $module == strtolower($item['app']) && $controller == strtolower($item['controller']) && $action == strtolower($item['action']) ? 'class="on"' : '';
            $param = ['menuid' => $parentid];
            //参数处理
            if (!empty($item['data'])) {
                $params = explode('=', $item['data']);
                $param[$params[0]] = $params[1];
            }
            if ($classname) {
                $str .= "<a href='javascript:;' $classname><em>" . $item['name'] . "</em></a><span>|</span>";
            } elseif ($parentid == $item['id'] || $parentid == $item['parentid'] && 1 == $item['display']) {
                $str .= "<a href='" . url($item['app'] . '/' . $item['controller'] . '/' . $item['action'], $param) . "'><em>" . $item['name'] . "</em></a><span>|</span>";
            }
        }
        //去除结束的字符：<span>|</span>
        $str = substr($str, 0, -14);
        return empty ($str) ? '' : '<div class="subnav" ><div class="content-menu ib-a blue line-x">' . $str . '</div ></div >';
    }


    /**
     * 判断是否有访问权限
     * @param $ruleid  角色ID
     * @return bool
     */
    public function checkAuth($ruleid)
    {
        //无需检测控制器
        if (in_array(strtolower($this->request->controller()), ['index'])) {
            return true;
        }
        //无需检测方法名
        if (in_array(strtolower($this->request->action()), ['get_left_menu'])) {
            return true;
        }
        //超级管理员具备所有权限
        if ($ruleid == 1) {
            return true;
        }
        //查询此次请求的地址,目前因为未将所有的操作写入到数据库中，默认未写入数据库的操作任何权限的管理员都可以操作
        $menuid = $this->where(['controller' => strtolower($this->request->controller()), 'action' => strtolower($this->request->action())])->value('id');
        if (empty($menuid)) {
            return true;
        }
        $rules_str = (new AuthGroup())->where(['id' => $ruleid])->value('rules');
        if (empty($rules_str)) {
            return false;
        }
        $rules = explode(',', $rules_str);
        if (!is_array($rules)) {
            return false;
        }
        return in_array($menuid, $rules);
    }


    /**
     * 排序
     * @param $array  排序数组
     * @return bool
     * @throws \Exception
     */
    public function listorder2(array $array)
    {
        $i = 0;
        foreach ($array as $id => $listorder) {
            if (false === $this->where(['id' => $id])->setField(['listorder' => $listorder])) {
                $i++;
            }
        }
        if ($i > 0) {
            $this->error = "排序失败{$i}条";
            return false;
        }
        return true;
    }

    /**删除
     * @param $id
     * @return bool
     */
    public function deleteInfo($id)
    {
        if (empty ($id)) {
            $this->error = 'ID不存在！';
            return false;
        }
        $info = $this->where([$this->pk => $id])->find();
        if (empty($info)) {
            $this->error = '您要删除的信息不存在！';
            return false;
        }
        //查询其下属所有分类
        $deleteid = $this->getChildNode($id);
        if (count($deleteid) > 1) {
            $this->error = '此菜单下有子类，不允许删除！';
            return false;
        }

        $status = $this->where(['id' => $id])->delete();
        if (false === $status) {
            $this->error = '删除信息错误！';
            return false;
        } else {
            $this->getCache();
            return true;
        }
    }

    public function getCache($options = ['type' => 'all'])
    {
        $list = $this->order('listorder asc')->select();
        if (empty($list)) {
            return false;
        }
        $cache = $root_menu = [];
        foreach ($list as $item) {
            $pk = (int)$item['id'];
            $cache[$pk] = $item->toArray();
            if ($item['parentid'] == 0 && $item['display'] == 1) {
                $root_menu[$pk] = $item->toArray();
            }
        }
        unset($list);
        cache('menu', $cache);
        cache('root_menu', $root_menu);
        //默认返回所有菜单
        return $options['type'] == 'all' ? $cache : $root_menu;
    }

    /**
     * 递归查询下属菜单
     * @param $id   要查询的菜单ID
     * @return array
     */
    private function getChildNode($id)
    {
        $this->child_node[] = intval($id);
        $list = $this->where(['parentid' => $id])->select();
        if (is_array($list)) {
            foreach ($list as $item) {
                $this->get_childnode($item['id']);
            }
        }
        return $this->child_node;
    }

}